package cn.you.GenghisKhan.common.utils;


import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Md5Util {

  /**
   * 获取String的MD5值
   *
   * @param password 字符串
   * @return 该字符串的MD5值
   */
  public static String getMD5(String password) {
    try {
      //获取 MessageDigest 对象，参数为 MD5 字符串，表示这是一个 MD5 算法（其他还有 SHA1 算法等）：
      MessageDigest md5 = MessageDigest.getInstance("MD5");
      //update(byte[])方法，输入原数据
      //类似StringBuilder对象的append()方法，追加模式，属于一个累计更改的过程
      md5.update(password.getBytes("UTF-8"));
      //digest()被调用后,MessageDigest对象就被重置，即不能连续再次调用该方法计算原数据的MD5值。可以手动调用reset()方法重置输入源。
      //digest()返回值16位长度的哈希值，由byte[]承接
      byte[] md5Array = md5.digest();
      //byte[]通常我们会转化为十六进制的32位长度的字符串来使用,本文会介绍三种常用的转换方法
      return bytesToHex1(md5Array);
    } catch (NoSuchAlgorithmException e) {
      return "";
    } catch (UnsupportedEncodingException e) {
      return "";
    }
  }

  private static String bytesToHex1(byte[] md5Array) {
    StringBuilder strBuilder = new StringBuilder();
    for (int i = 0; i < md5Array.length; i++) {
      int temp = 0xff & md5Array[i];//T
      String hexString = Integer.toHexString(temp);
      if (hexString.length() == 1) {//如果是十六进制的0f，默认只显示f，此时要补上0
        strBuilder.append("0").append(hexString);
      } else {
        strBuilder.append(hexString);
      }
    }
    return strBuilder.toString();
  }

  //通过java提供的BigInteger 完成byte->HexString
  private static String bytesToHex2(byte[] md5Array) {
    BigInteger bigInt = new BigInteger(1, md5Array);
    return bigInt.toString(16);
  }

  //通过位运算 将字节数组到十六进制的转换
  private static String bytesToHex3(byte[] byteArray) {
    char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    char[] resultCharArray = new char[byteArray.length * 2];
    int index = 0;
    for (byte b : byteArray) {
      resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];
      resultCharArray[index++] = hexDigits[b & 0xf];
    }
    return new String(resultCharArray);
  }}
